// 使用 SFINAE 和 Traits 进行选择性模板实例化

// 例子1：基于类型特性的处理器选择
// 假设我们需要一个处理器类，能够根据输入类型的特性选择不同的处理方法：
#include <iostream>
#include <type_traits>
#include <vector>
#include <string>

// 自定义 traits 检测类是否有 serialize 方法
template<typename T, typename = void>
struct has_serialize : std::false_type {};

// .serialize()是关键
template<typename T>
struct has_serialize<T, std::void_t<decltype(std::declval<T>().serialize())>> 
    : std::true_type {};

// 简化使用
template<typename T>
inline constexpr bool has_serialize_v = has_serialize<T>::value;

// 处理器类
template<typename T>
class Processor {
public:
    // 可序列化类型的处理方法 (SFINAE 启用)
    template<typename U = T, 
             typename std::enable_if_t<has_serialize_v<U>, int> = 0>
    void process(const U& data) {
        std::cout << "Processing serializable type: ";
        auto serialized = data.serialize();
        std::cout << serialized << std::endl;
    }
    
    // 数值类型的处理方法 (SFINAE 启用)
    template<typename U = T,
             typename std::enable_if_t<std::is_arithmetic_v<U> && !has_serialize_v<U>, int> = 0>
    void process(const U& data) {
        std::cout << "Processing numeric type: " << data * 2 << std::endl;
    }
    
    // 字符串类型的处理方法 (SFINAE 启用)
    template<typename U = T,
             typename std::enable_if_t<std::is_same_v<U, std::string> && !has_serialize_v<U>, int> = 0>
    void process(const U& data) {
        std::cout << "Processing string type: " << data + data << std::endl;
    }
    
    // 其他类型的处理方法 (SFINAE 启用)
    template<typename U = T,
             typename std::enable_if_t<!std::is_arithmetic_v<U> && 
                                      !std::is_same_v<U, std::string> && 
                                      !has_serialize_v<U>, int> = 0>
    void process(const U& data) {
        std::cout << "Processing generic type" << std::endl;
    }
};

// 可序列化的类
class User {
public:
    User(std::string name) : name_(name) {}
    
    std::string serialize() const {
        return "User(" + name_ + ")";
    }
    
private:
    std::string name_;
};

int main() {
    Processor<int> p1;
    p1.process(42);  // 调用数值处理方法
    
    Processor<std::string> p2;
    p2.process("Hello");  // 调用字符串处理方法
    
    Processor<User> p3;
    p3.process(User("John"));  // 调用可序列化处理方法
    
    Processor<std::vector<int>> p4;
    p4.process(std::vector<int>{1, 2, 3});  // 调用通用处理方法
    
    return 0;
}
